﻿namespace JunFan.Tests.Infrastructure
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using Domain;
    using Repositories;

    public class ItemBuilder
    {
        private Item _item;
        private DateTime _createDate;
        private bool _start;
        private DateTime? _startDate;
        private bool _complete;
        private DateTime? _completeDate;

        internal ItemBuilder()
        {
            _createDate = DateTime.Today.AddDays(-10);
        }

        # region Set properties
        public ItemBuilder CreatedOn(DateTime creationDate)
        {
            _createDate = creationDate;

            return this;
        }

        public ItemBuilder StartedOn(DateTime startDate)
        {
            _start = true;
            _startDate = startDate;
            
            return this;
        }

        public ItemBuilder CompletedOn(DateTime completeDate)
        {
            _complete = true;
            _completeDate = completeDate;

            return this;
        }
        # endregion Set properties

        # region Finalizers
        public Item Build()
        {
            return BuildIt();
        }

        public IEnumerable<Item> Build(int howMany)
        {
            BuildIt();
            
            return Clone(howMany);
        }

        public IEnumerable<Item> Create(IRepository<Item> repository, int howMany)
        {
            BuildIt();

            IEnumerable<Item> items = Clone(howMany);

            var enumerable = items as IList<Item> ?? items.ToList();
            
            foreach (var item in enumerable)
            {
                repository.Create(item);
            }

            return enumerable;
        }

        private IEnumerable<Item> Clone(int howMany)
        {
            var items = new List<Item>();

            for (int i = 0; i < howMany; i++)
            {
                items.Add(_item.Clone());
            }

            return items;
        }

        public Item Added(Board board)
        {
            BuildIt();

            return board.AddItem(_item);
        }
        #endregion Finalizers
        
        private Item BuildIt()
        {
            CreateItem();

            if (_start)
            {
                StartItem();
            }

            if (_complete)
            {
                CompleteItem();
            }

            return _item;
        }

        private void CompleteItem()
        {
            _item.CompletedOn = _completeDate;
        }

        private void StartItem()
        {
            _item.StartedOn = _startDate;
        }

        private void CreateItem()
        {
            _item = new Item
                {
                    Id = "1", // Fix this to create a unique Id
                    Description = "A new item",
                    CreatedOn = _createDate
                };
        }
    }
}